package cn.kgc.itrip.service.impl;


import cn.kgc.itrip.common.*;
import cn.kgc.itrip.dto.Dto;
import cn.kgc.itrip.dto.ItripTokenVO;
import cn.kgc.itrip.pojo.ItripUser;
import com.alibaba.fastjson.JSON;
import cz.mallat.uasparser.UserAgentInfo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

@Service
public class TokenServiceImpl implements TokenService{


    @Resource
    private RedisUtils redisUtils;

    /**
     *生成token
     * @param doRegister
     * @param userAgent
     * @return
     * @throws Exception
     *
     *   token：客户端标识-USERCODE-USERID-CREATIONDATE-RONDEM[6位]
     *   PC端：  token:PC-USERCODE-USERID-CREATIONDATE-RONDEM[6位]
     *   手机端：token:MOBILE-USERCODE-USERID-CREATIONDATE-RONDEM[6位]
     *
     *   token:PC-3066014fa0b10792e4a762-23-20170531133947-4f6496
     */
    @Override
    public String addToken(ItripUser doRegister, String userAgent)throws Exception {
        UserAgentInfo parse = UserAgentUtil.getUasParser().parse(userAgent);

        //凭借token
        StringBuffer stringBuffer=new StringBuffer("token");
        if (parse.getDeviceType().equals(UserAgentInfo.UNKNOWN)){
            //判断客户端
            if(UserAgentUtil.CheckAgent(userAgent)){
                stringBuffer.append("MOBILR-");
            }else{
                stringBuffer.append("PC-");
            }
        }else if(parse.getDeviceType().equals("window PC")){
            //如果是pc端
            stringBuffer.append("PC-");
        }else{
            stringBuffer.append("MOBILR-");
        }
        //使用StringBuffer进行拼接合成token格式
        //用户名加密后的32位
        stringBuffer.append(MD5.getMd5(doRegister.getUserCode(),32)+"-");
        //用户id
        stringBuffer.append(doRegister.getId()+"-");
        //token的生成时间
        stringBuffer.append(new SimpleDateFormat("yyyyMMddHHssmm").format(new Date())+"-");
        //随机数6位
        stringBuffer.append(MD5.getMd5(userAgent,6));
        return stringBuffer.toString();
    }


    /**
     * 置换token
     * @param token
     * @param userAgent
     * @return
     */
    @Override
    public Dto retoken(String token, String userAgent)throws Exception {
        //判断token是否存在
        if (!redisUtils.isExists(token)){
            return DtoUtil.returnFail("token不存在", ErrorCode.AUTH_TOKEN_INVALID);
        }
        //校验token
        String[] split = token.split("-");
        //已‘-’为分隔符，并用MD5工具类反编译userAgent,判断token的完整性
        if (!split[4].equals(MD5.getMd5(userAgent,6))){
            //如果token被截取，不安全
            return DtoUtil.returnFail("非法Token",ErrorCode.AUTH_ILLEGAL_USERCODE);
        }
        //不能频繁置换token()
        //返还原来的值，不再密封
        Date date = new SimpleDateFormat("yyyyMMdd").parse(split[3]);
        //当前时间-token生成的时间
        long pass=Calendar.getInstance().getTimeInMillis()-date.getTime();
        if (pass<1*60*1000){
            //距离生成的时间不到1小时，那么token不允许被置换
            return DtoUtil.returnFail("token保护期内，不允许频繁置换",ErrorCode.AUTH_REPLACEMENT_FAILED);
        }
        //获取用户对象
        String tokenValue = redisUtils.getValue(token);
        ItripUser user = JSON.parseObject(tokenValue, ItripUser.class);
        //生成新的token
        String token1 = addToken(user, userAgent);
        //保存新的token
        if(token1.startsWith("token:PC-")){
            redisUtils.setExpire(token1,JSON.toJSONString(user),2*60*60);
        }else{
            redisUtils.setValue(token1,JSON.toJSONString(user));
        }
        //旧token的续命
        redisUtils.setExpire(token,JSON.toJSONString(user),2);
        //返回前端
        ItripTokenVO tokenVO = new ItripTokenVO();
        tokenVO.setToken(token1);
        tokenVO.setExpTime(Calendar.getInstance().getTimeInMillis()+2*60*60*1000);
        tokenVO.setGenTime(Calendar.getInstance().getTimeInMillis());
        return DtoUtil.returnDataSuccess(tokenVO);
    }
}
